package com.ubi.core.framework;

import com.ubi.core.framework.cache.CacheTemplate;
import com.ubi.core.framework.monitor.health.RedisHealthChecker;
import com.ubi.core.framework.settings.ModuleSettings;
import com.ubi.core.json.JsonConverter;
import com.ubi.core.json.ObjectMapperCreator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author raymond
 */

public class DefaultRedisConfig {

    @Autowired
    protected ConfigurableEnvironment environment;

    @Autowired
    protected ModuleSettings moduleSettings;

    @Autowired
    JsonConverter jsonConverter;

    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(32);
        return jedisPoolConfig;
    }

    /* 支持多个redis server */
    @Bean
    @Primary
    public JedisConnectionFactory connectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setHostName("127.0.0.1");
        jedisConnectionFactory.setPort(6379);
        jedisConnectionFactory.setTimeout(5000);
        jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
        jedisConnectionFactory.setUsePool(true);
        String redisPwd = "";
        if (StringUtils.isNotBlank(redisPwd)) {
            jedisConnectionFactory.setPassword(redisPwd);
        }
        jedisConnectionFactory.setDatabase(0);
        jedisConnectionFactory.afterPropertiesSet();
        return jedisConnectionFactory;
    }

    @Bean(name = "redisTemplateForSpringCache")
    public RedisTemplate<Object, Object> redisTemplate() {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory());
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        serializer.setObjectMapper(ObjectMapperCreator.createDefaultObjectMapper());
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setHashKeySerializer(serializer);
        return redisTemplate;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate() {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(connectionFactory());
        // 可在key前添加指定字段
        // if (moduleSettings.isAppendTenantIdToCacheKey()) {
        // stringRedisTemplate.setKeySerializer(new
        // SaasStringRedisSerializer());
        // stringRedisTemplate.afterPropertiesSet();
        // }
        return stringRedisTemplate;
    }

    @Bean(name = "stringRedisTemplateForCommunal")
    public StringRedisTemplate stringRedisTemplateForCommunal() {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(connectionFactory());
        stringRedisTemplate.afterPropertiesSet();
        return stringRedisTemplate;
    }

    @Bean
    public CacheTemplate cacheTemplate() throws Exception {
        CacheTemplate cacheTemplate = new CacheTemplate();
        cacheTemplate.setJsonConverter(jsonConverter);
        cacheTemplate.setStringRedisTemplate(stringRedisTemplateForCommunal());
        // cacheTemplate.setVersion(environment.getRequiredProperty("redis.cache.version"));
        cacheTemplate.afterPropertiesSet();
        return cacheTemplate;
    }

    @Bean(name = "jdkSerializerRedisTemplate")
    public RedisTemplate<Object, Object> jdkSerializerRedisTemplate() {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory());
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        RedisSerializer<Object> jdkSerializer = new JdkSerializationRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(jdkSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(jdkSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    @Lazy
    public RedisHealthChecker redisHealthChecker() {
        return new RedisHealthChecker();
    }

}